package net.trevize.galatee;

import java.io.IOException;
import java.net.URI;
import java.util.Vector;

import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.Sort;
import org.apache.lucene.search.SortField;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;

/**
 * 
 * 
 * @author Nicolas James <nicolas.james@gmail.com> [[http://njames.trevize.net]]
 * InMemoryDescriptionIndex.java - Jun 10, 2010
 */

public class InMemoryDescriptionIndex {

	public static final String FIELD_IMAGE_ID = "FIELD_IMAGE_ID";
	public static final String FIELD_IMAGE_URI = "FIELD_IMAGE_URI";
	public static final String FIELD_IMAGE_DESCRIPTION = "FIELD_IMAGE_DESCRIPTION";
	private Vector<URI> v_uri;
	private Vector<Vector<Object>> data;
	private RAMDirectory index;
	private WhitespaceAnalyzer analyzer;
	private IndexWriter index_writer;
	private Searcher searcher;
	private QueryParser qparser;
	private Query query;
	private TopDocs topdocs;

	public InMemoryDescriptionIndex(Vector<URI> v_uri,
			Vector<Vector<Object>> data) {
		this.v_uri = v_uri;
		this.data = data;

		index = new RAMDirectory();

		try {
			analyzer = new WhitespaceAnalyzer();
			index_writer = new IndexWriter(index, analyzer, true,
					IndexWriter.MaxFieldLength.UNLIMITED);

			for (int i = 0; i < v_uri.size(); ++i) {
				String image_uri = v_uri.get(i).toString();

				String image_description = null;
				Vector<Object> image_data = data.get(i);
				if (image_data != null && image_data.size() != 0) {
					image_description = image_data.get(0).toString();

				}

				index_writer.addDocument(createDocument("" + i, image_uri,
						image_description));
			}

			//optimize and close the writer to finish building the index
			index_writer.optimize();
			index_writer.close();
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (LockObtainFailedException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		//build an IndexSearcher using the in-memory index
		try {
			searcher = new IndexSearcher(index);
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private Document createDocument(String image_id, String image_uri,
			String image_description) {
		Document doc = new Document();

		doc.add(new Field(FIELD_IMAGE_ID, image_id, Field.Store.YES,
				Field.Index.ANALYZED));

		doc.add(new Field(FIELD_IMAGE_URI, image_uri, Field.Store.YES,
				Field.Index.ANALYZED));

		doc.add(new Field(FIELD_IMAGE_DESCRIPTION, image_description,
				Field.Store.YES, Field.Index.ANALYZED));

		return doc;
	}

	public void search(String queryString) {
		topdocs = null;

		try {
			qparser = new MultiFieldQueryParser(Version.LUCENE_30,
					new String[] { FIELD_IMAGE_URI, FIELD_IMAGE_DESCRIPTION },
					analyzer);

			qparser.setAllowLeadingWildcard(true);

			query = qparser.parse(queryString);

			//we add a sort procedure in order to browse the results in the order of the images in the JScrollPanel.
			topdocs = searcher.search(query, null, searcher.maxDoc(), new Sort(
					new SortField(FIELD_IMAGE_ID, SortField.INT)));
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void search(String field, String queryString) {
		topdocs = null;

		try {
			qparser = new QueryParser(Version.LUCENE_30, field, analyzer);

			qparser.setAllowLeadingWildcard(true);

			query = qparser.parse(queryString);

			topdocs = searcher.search(query, v_uri.size());

			//display number of results.
			System.out.println(topdocs.totalHits + " results.");
		} catch (ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/***************************************************************************
	 * getters and setters.
	 **************************************************************************/

	public TopDocs getTopdocs() {
		return topdocs;
	}

	public void setTopdocs(TopDocs topdocs) {
		this.topdocs = topdocs;
	}

	public Searcher getSearcher() {
		return searcher;
	}

	public void setSearcher(Searcher searcher) {
		this.searcher = searcher;
	}

}
